/**
 * 验证器
 * @module Validators
 * @description 验证器模块聚合文件
 */
import { ValidationResult, ValidationRule, ValidationRuleObject } from './types';
import * as Validators from './validators/index'
export * from './validators/index';

/**
 * 验证规则处理函数
 * 
 * @param {any} value - 要验证的值
 * @param {ValidationRuleObject} rule - 验证规则对象
 * @returns {ValidationResult} 验证结果
 * @throws {Error} 当验证类型不存在时抛出异常
 */
export function validateRule(value: any, rule: ValidationRuleObject): ValidationResult {
  const { type, message, options } = rule;

  // 验证函数映射表
  const validators: Record<string, (value: any, options?: any) => ValidationResult> = {
    required: Validators.validateRequired,
    email: Validators.validateEmail,
    phone: Validators.validatePhone,
    url: Validators.validateUrl,
    min: Validators.validateMin,
    max: Validators.validateMax,
    minMax: Validators.validateMinMax,
    pattern: Validators.validatePattern,
    custom: Validators.validateCustom,
    idCard: Validators.validateIdCard,
    dateTime: Validators.validateDateTime,
    ip: Validators.validateIp,
    range: Validators.validateRange,
    number: Validators.validateNumber,
    charType: Validators.validateCharType,
    passwordStrength: Validators.validatePasswordStrength,
    file: Validators.validateFile,
    list: Validators.validateList
  };

  // 获取验证函数并调用
  const validator = validators[type];
  let result: ValidationResult;

  if (validator) {
    // 调用对应的验证函数
    result = validator(value, options);
  } else {
    // 未知的验证类型，抛出异常
    throw new Error(`未知的验证类型: ${type}`);
  }

  // 如果提供了自定义错误信息，使用自定义信息
  if (message && !result.valid) {
    result.message = message;
  }

  return result;
}

/**
 * 验证表单字段
 * 
 * @param {any} value - 字段值
 * @param {ValidationRule | ValidationRuleObject | (ValidationRule | ValidationRuleObject)[]} rules - 验证规则
 * @returns {string[]} 错误信息数组
 */
export function validateField(value: any, rules: ValidationRule | ValidationRuleObject | (ValidationRule | ValidationRuleObject)[]): string[] {
  const errors: string[] = [];

  // 处理规则数组
  if (Array.isArray(rules)) {
    for (const rule of rules) {
      const error = validateField(value, rule);
      errors.push(...error);
    }
  } else if (typeof rules === 'function') {
    // 处理函数类型规则
    const result = rules(value);
    if (result !== true && result !== undefined) {
      errors.push(result);
    }
  } else if (typeof rules === 'object' && rules !== null) {
    // 处理对象类型规则
    const result = validateRule(value, rules);
    if (!result.valid && result.message) {
      errors.push(result.message);
    }
  }

  return errors;
}

/**
 * 验证表单多个字段
 * 
 * @param {Record<string, any>} formData - 表单数据对象，键为字段名，值为字段值
 * @param {Record<string, ValidationRule | ValidationRuleObject | (ValidationRule | ValidationRuleObject)[]>} rulesMap - 验证规则映射表，键为字段名，值为该字段的验证规则
 * @returns {Record<string, string[]>} 按字段名组织的错误信息对象
 */
export function validateFields(
  formData: Record<string, any>,
  rulesMap: Record<string, ValidationRule | ValidationRuleObject | (ValidationRule | ValidationRuleObject)[]>): Record<string, string[]> {
  const errors: Record<string, string[]> = {};

  // 遍历所有字段规则
  for (const [fieldName, rules] of Object.entries(rulesMap)) {
    // 获取字段值
    const value = formData[fieldName];
    // 验证字段
    const fieldErrors = validateField(value, rules);
    // 如果有错误，添加到结果对象中
    if (fieldErrors.length > 0) {
      errors[fieldName] = fieldErrors;
    }
  }

  return errors;
}